#include <iostream>
#include <random>
#include <vector>
#include <string.h>
#include <thread>

// clang++ -o cpp_leak_sample -D_GLIBCXX_DEBUG -fsanitize=address -std=c++11 -O1 -g ./cpp_leak_sample.cpp
// clang++ -o cpp_leak_sample -std=c++11 -O1 -g ./cpp_leak_sample.cpp
// cmake .. -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
// 
// export MALLOC_CONF="prof:true,lg_prof_interval:20"
// LD_PRELOAD=/usr/local/lib/libjemalloc.so  ./cpp_leak_sample
// 其中lg_prof_interval:20中的20表示1MB(2^20)，prof:true是打开profiling。运行程序时，每分配(大约)1MB就会dump产生一个文件。
// 
void leak_sample1()
{
	std::uniform_int_distribution<unsigned> u(0, 9);
	std::default_random_engine e;
	char* ptr = nullptr;
	for (int i = 0; i < 10; ++i)
	{
		auto n = u(e);
		if (n < 5)
		{
			if (n < 2)
			{
				if (ptr != nullptr)
				{
					delete[]ptr;
				}
			}
			ptr = new char[i];
		}
		else
		{
		}
	}

	if (ptr != nullptr)
	{
		delete[]ptr;
	}
}

void leak_sample2()
{
	std::uniform_int_distribution<unsigned> u(0, 9);
	std::default_random_engine e;
	char* ptr = nullptr;
	std::vector<char*> vec;
	uint32_t leak_size = 0;
	for (int i = 0; i < 5; ++i)
	{
		auto n = u(e);
		if (n < 5)
		{
			ptr = new char[n*512];
			// 这个地方将会检查出内存越界
			// heap-buffer-overflow
			//memset((void *)ptr,0,n+1);
			vec.push_back(ptr);
			leak_size += n* 512;
			std::cout << "leak " << leak_size << " byte\n";
		}
		else
		{
			ptr = new char[n];
			vec.push_back(ptr);
			delete ptr;
		}
		std::this_thread::sleep_for(std::chrono::milliseconds(500));

		if (leak_size > 1024 * 1024) {
			vec.clear();
			leak_size = 0;
		}
	}
	
}

int main(int agrn, char* argc[])
{
	leak_sample1();
	leak_sample2();
	return 0;
}
